﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using System.Xml;
using System.IO;

namespace WarlockMapEditor
{
	public partial class WarlockMapEditor : Form
	{
		const int playingFieldWidth = 80;
		const int playingfieldHeight = 80;

		const int fieldWidth = 8;
		const int fieldHeight = 8;

		FieldState currentState;

		bool hasRaster = false;

		enum FieldState
		{
			Lava, //Lava = rot
			Rock, //Fester Boden = grau
			Player //Spieler = blau
		}

		FieldState[,] field = new FieldState[playingFieldWidth, playingfieldHeight];

		public static string Description { get; set; }
		public static string Author { get; set; }
		public static DateTime ReleaseDate { get; set; }

		string exePath = null;
		string savePath = null;

		Image checkMark;
		//Image stone;
		//Image lava;
		//Image player;

		public WarlockMapEditor()
		{
			InitializeComponent();

			ClientSize = new Size(playingFieldWidth * fieldWidth, playingfieldHeight * fieldHeight);

			exePath = Path.GetDirectoryName(Application.ExecutablePath);
			checkMark = Image.FromFile(exePath + @"\gfx\haken1.gif");
			//stone = Image.FromFile(exePath + @"\gfx\fels.jpg");
			//lava = Image.FromFile(exePath + @"\gfx\lava.jpg");
			//player = Image.FromFile(exePath + @"\gfx\spieler.gif");

			Reset();
		}

		private void Reset()
		{
			currentState = FieldState.Lava;

			lavaToolStripMenuItem.Image = checkMark;
			festerBodenToolStripMenuItem.Image = null;
			spielerToolStripMenuItem.Image = null;

			hasRaster = false;

			for (int i = 0; i < playingFieldWidth; i++)
			{
				for (int j = 0; j < playingfieldHeight; j++)
				{
					field[i, j] = FieldState.Lava;
				}
			}

			Invalidate();

			Description = null;
			Author = null;
			ReleaseDate = DateTime.Today;
		}

		private void rasterEinToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (hasRaster)
				hasRaster = false;
			else
				hasRaster = true;

			Invalidate();
		}

		private void lavaToolStripMenuItem_Click(object sender, EventArgs e)
		{
			currentState = FieldState.Lava;

			lavaToolStripMenuItem.Image = checkMark;
			festerBodenToolStripMenuItem.Image = null;
			spielerToolStripMenuItem.Image = null;
		}

		private void festerBodenToolStripMenuItem_Click(object sender, EventArgs e)
		{
			currentState = FieldState.Rock;

			festerBodenToolStripMenuItem.Image = checkMark;
			lavaToolStripMenuItem.Image = null;
			spielerToolStripMenuItem.Image = null;
		}

		private void spielerToolStripMenuItem_Click(object sender, EventArgs e)
		{
			currentState = FieldState.Player;

			spielerToolStripMenuItem.Image = checkMark;
			lavaToolStripMenuItem.Image = null;
			festerBodenToolStripMenuItem.Image = null;
		}

		private void WarlockMapEditor_Paint(object sender, PaintEventArgs e)
		{
			Graphics g = e.Graphics;

			for (int i = 0; i < playingFieldWidth; i++)
			{
				for (int j = 0; j < playingfieldHeight; j++)
				{
					if (field[i, j] == FieldState.Lava)
						//g.DrawImage(lavaToolStripMenuItem, new RectangleF(j * fieldWidth, i * fieldHeight, fieldWidth, fieldHeight));
						g.FillRectangle(Brushes.Red, new Rectangle(j * fieldWidth, i * fieldHeight, fieldWidth, fieldHeight));
					else if (field[i, j] == FieldState.Player)
						g.FillRectangle(Brushes.Blue, new Rectangle(j * fieldWidth, i * fieldHeight, fieldWidth, fieldHeight));
					else
						g.FillRectangle(Brushes.Gray, new Rectangle(j * fieldWidth, i * fieldHeight, fieldWidth, fieldHeight));
				}
			}

			if (hasRaster)
			{
				for (int i = 1; i < playingFieldWidth; i++)
				{
					g.DrawLine(Pens.Black, new Point(i * fieldWidth, 0), new Point(i * fieldWidth, fieldHeight * playingfieldHeight));
					g.DrawLine(Pens.Black, new Point(0, i * fieldHeight), new Point(fieldWidth * playingFieldWidth, i * fieldHeight));
				}
			}
		}

		private void WarlockMapEditor_MouseDown(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left &&
				e.X < (fieldWidth * playingFieldWidth) &&
				e.Y < (fieldHeight * playingfieldHeight) &&
				e.X > 0 &&
				e.Y > 0)
			{
				int horzNumber = e.X / fieldWidth;
				int vertNumber = e.Y / fieldHeight;

				if (currentState == FieldState.Lava)
					field[vertNumber, horzNumber] = FieldState.Lava;
				else if (currentState == FieldState.Player)
					field[vertNumber, horzNumber] = FieldState.Player;
				else
					field[vertNumber, horzNumber] = FieldState.Rock;

				Invalidate(new Rectangle(horzNumber * fieldWidth, vertNumber * fieldHeight, fieldWidth, fieldHeight));
			}
		}

		private void WarlockMapEditor_MouseMove(object sender, MouseEventArgs e)
		{
			if (e.Button == MouseButtons.Left && 
				e.X < (fieldWidth * playingFieldWidth) && 
				e.Y < (fieldHeight * playingfieldHeight) &&
				e.X > 0 && 
				e.Y > 0)
			{
				int horzNumber = e.X / fieldWidth;
				int vertNumber = e.Y / fieldHeight;

				if (currentState == FieldState.Lava)
					field[vertNumber, horzNumber] = FieldState.Lava;
				else if (currentState == FieldState.Player)
					field[vertNumber, horzNumber] = FieldState.Player;
				else
					field[vertNumber, horzNumber] = FieldState.Rock;

				Invalidate(new Rectangle(horzNumber * fieldWidth, vertNumber * fieldHeight, fieldWidth, fieldHeight));
			}
		}

		private void neuToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (savePath == null)
			{
				DialogResult result = MessageBox.Show("Sie haben Ihre Map noch nicht gespeichert.\nMöchten Sie dies noch tun?", "Speichern", MessageBoxButtons.YesNoCancel);

				if (result == DialogResult.Yes)
				{
					SaveFileDialog sfd = new SaveFileDialog();
					sfd.Filter = "XML-Dateien (*.xml)|*.xml";
					sfd.AddExtension = true;

					if (sfd.ShowDialog() != DialogResult.OK)
						return;

					savePath = sfd.FileName;

					CreateXMLDocument();
				}
			}
			else
			{
				Reset();
			}
		}

		private void öffnenToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (savePath == null)
			{
				DialogResult result = MessageBox.Show("Sie haben Ihre Map noch nicht gespeichert.\nMöchten Sie dies noch tun?", "Speichern", MessageBoxButtons.YesNoCancel);

				if (result == DialogResult.Yes)
				{
					SaveFileDialog sfd = new SaveFileDialog();
					sfd.Filter = "XML-Dateien (*.xml)|*.xml";
					sfd.AddExtension = true;

					if (sfd.ShowDialog() != DialogResult.OK)
						return;

					savePath = sfd.FileName;

					CreateXMLDocument();
				}
			}
			else
			{
				Reset();

				OpenFileDialog ofd = new OpenFileDialog();
				ofd.Filter = "XML-Dateien (*.xml)|*.xml";

				if (ofd.ShowDialog() == DialogResult.OK)
				{
					XmlDocument doc = new XmlDocument();
					doc.Load(ofd.FileName);

					XmlNode mapInfo = doc.SelectSingleNode("/WarlockMap/MapInfo");

					Author = mapInfo.Attributes["Author"].Value.ToString();
					Description = mapInfo.Attributes["Description"].Value.ToString();

					string[] temp = mapInfo.Attributes["ReleaseDate"].Value.ToString().Split(new Char[] { '.' });
					ReleaseDate = new DateTime(Convert.ToInt32(temp[2]), Convert.ToInt32(temp[1]), Convert.ToInt32(temp[0]));

					foreach (XmlNode node in doc.SelectSingleNode("/WarlockMap/MapContent"))
					{
						if (node.Name == "Tile")
						{
							temp = node.Attributes["Position"].Value.ToString().Split(new Char[] { ';' });

							int xPosition = Convert.ToInt32(temp[0]);
							int yPosition = Convert.ToInt32(temp[1]);

							if (node.Attributes["Type"].Value == "Lava")
								field[xPosition, yPosition] = FieldState.Lava;
							else if (node.Attributes["Type"].Value == "Rock")
								field[xPosition, yPosition] = FieldState.Rock;
						}
						else if (node.Name == "Player")
						{
							temp = node.Attributes["Position"].Value.ToString().Split(new Char[] { ';' });

							int xPosition = Convert.ToInt32(temp[0]);
							int yPosition = Convert.ToInt32(temp[1]);

							field[xPosition, yPosition] = FieldState.Player;
						}
					}
				}
			}

			Invalidate();
		}

		private void CreateXMLDocument()
		{
			XmlDocument doc = new XmlDocument();
			XmlNode rootNode = doc.CreateElement("WarlockMap");
			doc.AppendChild(rootNode);

			XmlNode mapInfo = doc.CreateElement("MapInfo");
			rootNode.AppendChild(mapInfo);

			XmlAttribute author = doc.CreateAttribute("Author");
			author.InnerText = Author;
			mapInfo.Attributes.Append(author);

			XmlAttribute description = doc.CreateAttribute("Description");
			description.InnerText = Description;
			mapInfo.Attributes.Append(description);

			XmlAttribute releaseDate = doc.CreateAttribute("ReleaseDate");
			releaseDate.InnerText = ReleaseDate.ToShortDateString();
			mapInfo.Attributes.Append(releaseDate);

			XmlNode mapContent = doc.CreateElement("MapContent");
			rootNode.AppendChild(mapContent);

			for (int i = 0; i < playingFieldWidth; i++)
			{
				for (int j = 0; j < playingfieldHeight; j++)
				{
					XmlNode tile = doc.CreateElement("Tile");
					mapContent.AppendChild(tile);

					XmlAttribute type = doc.CreateAttribute("Type");

					if (field[i, j] == FieldState.Lava || field[i, j] == FieldState.Player)
						type.InnerText = "Lava";
					else
						type.InnerText = "Rock";

					tile.Attributes.Append(type);

					XmlAttribute position = doc.CreateAttribute("Position");
					position.InnerText = i.ToString() + ";" + j.ToString();
					tile.Attributes.Append(position);

					if (field[i, j] == FieldState.Player)
					{
						XmlNode player = doc.CreateElement("Player");
						mapContent.AppendChild(player);

						XmlAttribute playerPosition = doc.CreateAttribute("Position");
						playerPosition.InnerText = i.ToString() + ";" + j.ToString();
						player.Attributes.Append(playerPosition);

						XmlAttribute lifePoints = doc.CreateAttribute("LifePoints");
						lifePoints.InnerText = "100";
						player.Attributes.Append(lifePoints);
					}
				}
			}

			doc.Save(savePath);
		}

		private void speichernToolStripMenuItem_Click(object sender, EventArgs e)
		{
			if (savePath == null)
			{
				SaveFileDialog sfd = new SaveFileDialog();
				sfd.Filter = "XML-Dateien (*.xml)|*.xml";
				sfd.AddExtension = true;

				if (sfd.ShowDialog() != DialogResult.OK)
					return;

				savePath = sfd.FileName;

				CreateXMLDocument();
			}
			else
			{
				CreateXMLDocument();
			}
		}

		private void speichernUnterToolStripMenuItem_Click(object sender, EventArgs e)
		{
			SaveFileDialog sfd = new SaveFileDialog();
			sfd.Filter = "XML-Dateien (*.xml)|*.xml";
			sfd.AddExtension = true;

			if (sfd.ShowDialog() != DialogResult.OK)
				return;

			savePath = sfd.FileName;

			CreateXMLDocument();
		}

		private void beendenToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Close();
		}

		private void beschreibungToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Description frmDescription = new Description();
			frmDescription.Show(this);
		}

		private void autorToolStripMenuItem_Click(object sender, EventArgs e)
		{
			Author frmAuthor = new Author();
			frmAuthor.Show(this);
		}

		private void erscheinungsjahrToolStripMenuItem_Click(object sender, EventArgs e)
		{
			ReleaseDate frmReleaseDate = new ReleaseDate();
			frmReleaseDate.Show();
		}

		private void infoToolStripMenuItem_Click(object sender, EventArgs e)
		{
			MessageBox.Show(this, "Dies ist der offizielle MapEditor von Warlock.\nProgrammiert von Vitab, Speedy_92 und Wasabi.");
		}

		private void WarlockMapEditor_FormClosing(object sender, FormClosingEventArgs e)
		{
			if (savePath == null)
			{
				DialogResult result = MessageBox.Show("Sie haben Ihre Map noch nicht gespeichert.\nMöchten Sie dies noch tun?", "Speichern", MessageBoxButtons.YesNoCancel);

				if (result == DialogResult.Yes)
				{
					SaveFileDialog sfd = new SaveFileDialog();
					sfd.Filter = "XML-Dateien (*.xml)|*.xml";
					sfd.AddExtension = true;

					if (sfd.ShowDialog() != DialogResult.OK)
						return;

					savePath = sfd.FileName;

					CreateXMLDocument();
				}
				else if (result == DialogResult.Cancel)
					e.Cancel = true;
			}
		}

	
	}
}